/*
 *
 *  This file is part of the SIRIUS library for analyzing MS and MS/MS data
 *
 *  Copyright (C) 2013-2020 Kai Dührkop, Markus Fleischauer, Marcus Ludwig, Martin A. Hoffman and Sebastian Böcker,
 *  Chair of Bioinformatics, Friedrich-Schilller University.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 3 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with SIRIUS. If not, see <https://www.gnu.org/licenses/lgpl-3.0.txt>
 */

package de.unijena.bioinf.ChemistryBase.ms.ft;

import de.unijena.bioinf.ChemistryBase.chem.MolecularFormula;
import de.unijena.bioinf.ChemistryBase.chem.PrecursorIonType;
import de.unijena.bioinf.ChemistryBase.ms.AnnotatedPeak;
import de.unijena.bioinf.ms.annotations.TreeAnnotation;

import java.util.Optional;

/**
 * This annotation is set whenever we remove an adduct from the tree (see IonTreeUtils).
 * If a fragment looses an adduct, we neutralize the molecular formula, but add the ImplicitAdduct annotation.
 * If a loss looses an adduct, the adduct formula is subtracted from the loss formula and the ImplicitAdduct annotation
 * is set. However, the subtree is then already neutralized and does not get an ImplicitAdduct annotation.
 */
public class ImplicitAdduct implements TreeAnnotation  {

    protected final MolecularFormula adductFormula;
    protected final Optional<AnnotatedPeak> implicitPeak;
    protected final double score;

    private static final ImplicitAdduct NO_ADDUCT = new ImplicitAdduct(MolecularFormula.emptyFormula());

    public static ImplicitAdduct none() {
        return NO_ADDUCT;
    }

    public ImplicitAdduct() {
        this(MolecularFormula.emptyFormula());
    }

    public ImplicitAdduct(MolecularFormula adductFormula) {
        this(adductFormula, Optional.empty(), 0d);
    }

    public ImplicitAdduct(MolecularFormula adductFormula, Optional<AnnotatedPeak> implicitPeak, double score) {
        this.adductFormula = adductFormula;
        this.implicitPeak = implicitPeak;
        this.score = score;
    }

    public MolecularFormula getAdductFormula() {
        return adductFormula;
    }

    public Optional<AnnotatedPeak> getImplicitPeak() {
        return implicitPeak;
    }

    public double getScore() {
        return score;
    }

    public boolean hasImplicitAdduct() {
        return !adductFormula.isEmpty();
    }

}
